﻿#region LicenseInfo
/*
 * WoW Automation
 * Copyright 2008, 2009
 * Michael Sutton
 * 
 * This file is part of Wow Automation.
 * 
 * Wow Automation is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Wow Automation is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Wow Automation.  If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Windows.Forms;
using System.Drawing;

namespace Automation
{
    public class KeyPushUtils
    {

        private static void initGlobals()
        {
            CommonVariables.PlayerStatus.AB = false;
            CommonVariables.PlayerStatus.abGraveYard1 = false;
            CommonVariables.PlayerStatus.abGraveYard2 = false;
            CommonVariables.PlayerStatus.abGraveYard3 = false;
            CommonVariables.PlayerStatus.abGraveYard4 = false;
            CommonVariables.PlayerStatus.abGraveYard5 = false;
            CommonVariables.PlayerStatus.abGraveYard6 = false;
            CommonVariables.PlayerStatus.abGraveYard7 = false;

            CommonVariables.PlayerStatus.AV = false;
            CommonVariables.PlayerStatus.avGraveYard2 = false;
            CommonVariables.PlayerStatus.avGraveYard1 = false;
            CommonVariables.PlayerStatus.avGraveYard3 = false;
            CommonVariables.PlayerStatus.avGraveYard4 = false;
            CommonVariables.PlayerStatus.avGraveYard5 = false;
            CommonVariables.PlayerStatus.avGraveYard6 = false;
            CommonVariables.PlayerStatus.avGraveYard7 = false;
            CommonVariables.PlayerStatus.avGraveYard8 = false;

            CommonVariables.PlayerStatus.Darnassus = false;
            CommonVariables.PlayerStatus.Dead = false;
            CommonVariables.PlayerStatus.EOS = false;
            CommonVariables.PlayerStatus.eosGraveYard1 = false;
            CommonVariables.PlayerStatus.eosGraveYard2 = false;
            CommonVariables.PlayerStatus.eosGraveYard3 = false;
            CommonVariables.PlayerStatus.eosGraveYard4 = false;
            CommonVariables.PlayerStatus.eosGraveYard5 = false;
            CommonVariables.PlayerStatus.InRaid = false;
            CommonVariables.PlayerStatus.Inside = false;
            CommonVariables.PlayerStatus.Outside = false;
            CommonVariables.PlayerStatus.IronForge = false;
            CommonVariables.PlayerStatus.Shatrath = false;
            CommonVariables.PlayerStatus.Stormwind = false;
            CommonVariables.PlayerStatus.WSG = false;
            CommonVariables.PlayerStatus.wsgGraveYard = false;
            CommonVariables.PlayerStatus.inQueue = false;
            CommonVariables.PlayerStatus.X = -1;
            CommonVariables.PlayerStatus.Y = -1;
            CommonVariables.PlayerStatus.Facing = -1;
            CommonVariables.PlayerStatus.ValidScan = false;
        }
        private static Bitmap TranslateImage(Bitmap bmp)
        {
            int x;
            int width = bmp.Width;
            Color pixelColor;
            CommonVariables.BGinfo lplayerStatus = new CommonVariables.BGinfo
                                                       {
                                                           X = (-1),
                                                           Y = (-1),
                                                           Facing = (-1),
                                                           Quit = CommonVariables.PlayerStatus.Quit
                                                       };
            initGlobals( );
        
            bool foundStart = false;
            bool foundX = false;
            bool foundY = false;
            bool foundFacing = false;
            bool foundEnd = false;

            for (x = 0; x < width; x++)
            {

                pixelColor = bmp.GetPixel(x, 3);
                if (pixelColor == PlayerStates.MarkStart) { foundStart = true; }
                if (pixelColor == PlayerStates.MarkX) { foundX = true; x += 4; pixelColor = bmp.GetPixel(x, 3); }
                if (pixelColor == PlayerStates.MarkY) { foundY = true; x += 4; pixelColor = bmp.GetPixel(x, 3); }
                if (pixelColor == PlayerStates.MarkFacing) { foundFacing = true; x += 4; pixelColor = bmp.GetPixel(x, 3); }
                if (pixelColor == PlayerStates.MarkEnd) { foundEnd = true; }

                if (foundX && lplayerStatus.X == -1)
                {
                    lplayerStatus.X = Convert.ToInt32(string.Format("0x00{0}{1}{2}", pixelColor.R.ToString("X2"), pixelColor.G.ToString("X2"), pixelColor.B.ToString("X2")), 16);
                }

                if (foundY && lplayerStatus.Y == -1)
                {
                    lplayerStatus.Y = Convert.ToInt32(string.Format("0x00{0}{1}{2}", pixelColor.R.ToString("X2"), pixelColor.G.ToString("X2"), pixelColor.B.ToString("X2")), 16);
                }

                if (foundFacing && lplayerStatus.Facing == -1)
                {
                    lplayerStatus.Facing = Convert.ToInt32(string.Format("0x00{0}{1}{2}", pixelColor.R.ToString("X2"), pixelColor.G.ToString("X2"), pixelColor.B.ToString("X2")), 16);
                }

                if (foundX != true)
                {
                    if (pixelColor == PlayerStates.AB) { lplayerStatus.AB = true; }
                    if (pixelColor == PlayerStates.abGraveYard1) { lplayerStatus.abGraveYard1 = true; }
                    if (pixelColor == PlayerStates.abGraveYard2) { lplayerStatus.abGraveYard2 = true; }
                    if (pixelColor == PlayerStates.abGraveYard3) { lplayerStatus.abGraveYard3 = true; }
                    if (pixelColor == PlayerStates.abGraveYard4) { lplayerStatus.abGraveYard4 = true; }
                    if (pixelColor == PlayerStates.abGraveYard5) { lplayerStatus.abGraveYard5 = true; }
                    if (pixelColor == PlayerStates.abGraveYard6) { lplayerStatus.abGraveYard6 = true; }
                    if (pixelColor == PlayerStates.abGraveYard7) { lplayerStatus.abGraveYard7 = true; }

                    if (pixelColor == PlayerStates.AV) { lplayerStatus.AV = true; }
                    if (pixelColor == PlayerStates.avGraveYard0) { lplayerStatus.avGraveYard1 = true; }
                    if (pixelColor == PlayerStates.avGraveYard1) { lplayerStatus.avGraveYard2 = true; }
                    if (pixelColor == PlayerStates.avGraveYard2) { lplayerStatus.avGraveYard3 = true; }
                    if (pixelColor == PlayerStates.avGraveYard3) { lplayerStatus.avGraveYard4 = true; }
                    if (pixelColor == PlayerStates.avGraveYard4) { lplayerStatus.avGraveYard5 = true; }
                    if (pixelColor == PlayerStates.avGraveYard5) { lplayerStatus.avGraveYard6 = true; }
                    if (pixelColor == PlayerStates.avGraveYard6) { lplayerStatus.avGraveYard7 = true; }
                    if (pixelColor == PlayerStates.avGraveYard7) { lplayerStatus.avGraveYard8 = true; }

                    if (pixelColor == PlayerStates.Darnasus) { lplayerStatus.Darnassus = true; }
                    if (pixelColor == PlayerStates.Dead) { lplayerStatus.Dead = true; }
                    if (pixelColor == PlayerStates.EOS) { lplayerStatus.EOS = true; }
                    if (pixelColor == PlayerStates.eosGraveYard1) { lplayerStatus.eosGraveYard1 = true; }
                    if (pixelColor == PlayerStates.eosGraveYard2) { lplayerStatus.eosGraveYard2 = true; }
                    if (pixelColor == PlayerStates.eosGraveYard3) { lplayerStatus.eosGraveYard3 = true; }
                    if (pixelColor == PlayerStates.eosGraveYard4) { lplayerStatus.eosGraveYard4 = true; }
                    if (pixelColor == PlayerStates.eosGraveYard5) { lplayerStatus.eosGraveYard5 = true; }
                    if (pixelColor == PlayerStates.inQueue) { lplayerStatus.inQueue = true; }
                    if (pixelColor == PlayerStates.InRaid) { lplayerStatus.InRaid = true; }
                    if (pixelColor == PlayerStates.Inside) { lplayerStatus.Inside = true; }
                    if (pixelColor == PlayerStates.IronForge) { lplayerStatus.IronForge = true; }
                    if (pixelColor == PlayerStates.OutSide) { lplayerStatus.Outside = true; }
                    if (pixelColor == PlayerStates.Shattrath) { lplayerStatus.Shatrath = true; }
                    if (pixelColor == PlayerStates.StormWind) { lplayerStatus.Stormwind = true; }
                    if (pixelColor == PlayerStates.wsg) { lplayerStatus.WSG = true; }
                    if (pixelColor == PlayerStates.wsgGraveYard) { lplayerStatus.wsgGraveYard = true; }
                    if (pixelColor == PlayerStates.SilverMoon) { lplayerStatus.SilverMoon = true; }
                }
                bmp.SetPixel(x, 3, Color.Blue);
            
            }
            if (foundStart && foundEnd)
            {
                CommonVariables.PlayerStatus = lplayerStatus;
                CommonVariables.PlayerStatus.ValidScan = true;
                //FrostWolf Relif hut always returns a non existant subzone
                if ((lplayerStatus.X >= 4980) && (lplayerStatus.X <= 4999) &&
                    (lplayerStatus.Y >= 9128) && (lplayerStatus.Y <= 9142) &&
                    lplayerStatus.AV)
                {
                    CommonVariables.PlayerStatus.avGraveYard8 = true;
                }

                if ((lplayerStatus.X >= 5640) && (lplayerStatus.X <= 5645) &&
                    (lplayerStatus.Y >= 8929) && (lplayerStatus.Y <= 8934) &&
                    lplayerStatus.AV)
                {
                    CommonVariables.PlayerStatusOld.SilverMoon = true;
                    CommonVariables.PlayerStatusOld.AV = false;
                }

                if ((lplayerStatus.X >= 4930) && (lplayerStatus.X <= 4947) &&
                    (lplayerStatus.Y >= 7330) && (lplayerStatus.Y <= 7340) &&
                    lplayerStatus.EOS)
                {
                    CommonVariables.PlayerStatusOld.SilverMoon = true;
                    CommonVariables.PlayerStatusOld.AV = false;
                }

                if ((lplayerStatus.X >= 6930) && (lplayerStatus.X <= 6958) && (lplayerStatus.Y >= 6777) && (lplayerStatus.Y <= 6797) && lplayerStatus.AB)
                {
                    CommonVariables.PlayerStatusOld.SilverMoon = true;
                    CommonVariables.PlayerStatusOld.WSG = false;
                    CommonVariables.PlayerStatusOld.Dead = true;
                }

                if (CommonVariables.PlayerStatus.Quit) CommonVariables.PlayerStatus.ValidScan = false;
            }
            else
            {
                CommonVariables.PlayerStatus.ValidScan = false;
            }
            return bmp;
        }

        public Bitmap ScrapeScreen()
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            Bitmap bmp = null;
            if (!hwnd.Equals(IntPtr.Zero))
            {
                Win32Support.RECT myRect = new Win32Support.RECT();
                Win32Support.GetWindowRect(hwnd, ref myRect);
                int winFrameWidth = Win32Support.GetSystemMetrics(Win32Support.SM_CXSIZEFRAME);
                int winCaptionHeight = Win32Support.GetSystemMetrics(Win32Support.SM_CYCAPTION);
                //adjust for just the size of the window
                myRect.top += winCaptionHeight + winFrameWidth;
                myRect.bottom -= winFrameWidth;
                myRect.left += winFrameWidth;
                myRect.right -= winFrameWidth;

                //bahh just get the part were looking for.
                myRect.bottom = myRect.top + 8;
                myRect.right = myRect.left + 75;

                //only retrieve the part of the screen we need
                bmp = Win32Support.GetScreenImage(Win32Support.GetDesktopWindow(), myRect);
            }

            if (bmp != null)
            {
                return TranslateImage(bmp);
            }
            return null;

        }


        public void SendKeyHover(int timeMilliSeconds)
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            if (CommonVariables.PlayerStatus.Dead) return;
            if (CommonVariables.PlayerStatus.Quit) { return; }
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            if (CommonVariables.PlayerStatus.X == -1) return;


            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYDOWN, (IntPtr)Keys.ControlKey, IntPtr.Zero);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYDOWN, (IntPtr)Keys.Menu, IntPtr.Zero);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYDOWN, (IntPtr)Keys.B, IntPtr.Zero);
            
            CommonVariables.Pause(timeMilliSeconds);
            
            
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYUP, (IntPtr)Keys.B, IntPtr.Zero);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYUP, (IntPtr)Keys.Menu, IntPtr.Zero);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYUP, (IntPtr)Keys.ControlKey, IntPtr.Zero);
        }
        public void SendKey(Keys key, int timeMilliSeconds)
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            ScrapeScreen();
            if (CommonVariables.PlayerStatus.Dead) { return; }
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            IntPtr keytosend = (IntPtr)key;
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYDOWN, keytosend, IntPtr.Zero);
            for (int i = 0; i <= timeMilliSeconds; i++)
            {
                CommonVariables.Pause(1);
                Application.DoEvents();
            }

            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_KEYUP, keytosend, IntPtr.Zero);
        }

        public void SendKeyAndAdjust(Keys key, int timeMilliSeconds, int destX, int destY)
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            ScrapeScreen();
            if (CommonVariables.PlayerStatus.Dead)  return;
            if (CommonVariables.PlayerStatus.InRaid == false &&
                (
                    CommonVariables.PlayerStatus.SilverMoon == false &&
                    CommonVariables.PlayerStatus.Darnassus == false)
                ) return;
            if (CommonVariables.PlayerStatus.Quit) return;
            if (!CommonVariables.PlayerStatus.ValidScan) return;
            if (CommonVariables.PlayerStatus.X == -1) return;
         
            Win32Support.RECT myRect = new Win32Support.RECT();
            Win32Support.GetWindowRect(hwnd, ref myRect);

            int dest_x = ((myRect.right - myRect.left) / 2);
            int dest_y = ((myRect.bottom - myRect.top) / 2);


            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_RBUTTONDOWN, (IntPtr)0, MakeLParam(dest_x, dest_y));
            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_LBUTTONDOWN, (IntPtr)0, MakeLParam(dest_x, dest_y));
            Double Angle = DirectionToFace(destX, destY);
            FaceDirectionMouse2((float)Angle, 1, 1);
            CommonVariables.Pause(timeMilliSeconds);
            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_LBUTTONUP, (IntPtr)0, MakeLParam(dest_x, dest_y));
            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_RBUTTONUP, (IntPtr)0, MakeLParam(dest_x, dest_y));

        }


        static IntPtr MakeLParam(int LoWord, int HiWord)
        {
            return new IntPtr((HiWord << 16) | (LoWord & 0xffff));
        }
        public void MouseClick(int x, int y)
        {
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            Win32Support.RECT myRect = new Win32Support.RECT();
            Win32Support.GetWindowRect(hwnd, ref myRect);

            int dest_x = (myRect.left) + x;// *65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            int dest_y = ((myRect.top) + y);// *65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;


            Win32Support.SetCursorPos(dest_x, dest_y);
            System.Threading.Thread.Sleep(50);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_RBUTTONDOWN, (IntPtr)0, (IntPtr)0);
            System.Threading.Thread.Sleep(50);
            System.Threading.Thread.Sleep(50);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_RBUTTONUP, (IntPtr)0, (IntPtr)0);

        }
        public void MouseMove_new(int ticks)
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            if (!CommonVariables.PlayerStatus.ValidScan) return;
            if (CommonVariables.PlayerStatus.Quit) return;
            if (CommonVariables.PlayerStatus.X == -1) return;
            Win32Support.RECT myRect = new Win32Support.RECT();
            Win32Support.GetWindowRect(hwnd, ref myRect);

            int dest_x = 504;
            int dest_y = 272;

            Win32Support.SetFocus(hwnd);
            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_SETFOCUS, (IntPtr)0, (IntPtr)0);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_RBUTTONDOWN, (IntPtr)WindowsMessageCode.ClickModifier.MK_RBUTTON, MakeLParam(dest_x, dest_y));
            CommonVariables.Pause(50);
            if (ticks <= -0.1)
            {
                for (int i = 0; i != ticks; i--)
                {
                    dest_x -= 1;
                    i--;
                    Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_MOUSEMOVE, (IntPtr)WindowsMessageCode.ClickModifier.MK_RBUTTON, MakeLParam(dest_x, dest_y));
                    dest_x++;
                }
            }
            else
            {
                for (int i = 0; i <= ticks; i++)
                {
                    dest_x += 1;
                    i++;
                    Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_MOUSEMOVE, (IntPtr)WindowsMessageCode.ClickModifier.MK_RBUTTON, MakeLParam(dest_x, dest_y));

                    dest_x--;
                }
            }
            CommonVariables.Pause(50);
            Win32Support.PostMessage(hwnd, WindowsMessageCode.WM_RBUTTONUP, (IntPtr)0, MakeLParam(dest_x, dest_y));
            CommonVariables.Pause(2050);
        }
        public void Wait(int ms)
        {

                CommonVariables.Pause(ms);
        }
        public void MouseMove(int ticks )
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            Win32Support.RECT myRect = new Win32Support.RECT();
            Win32Support.GetWindowRect(hwnd, ref myRect);

            int dest_x = ((myRect.right - myRect.left) / 2);// *65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            int dest_y = ((myRect.bottom - myRect.top) / 2);// *65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;

            ScrapeScreen();
            if (CommonVariables.PlayerStatus.Dead) { return; }
            if (CommonVariables.PlayerStatus.Quit) { return; }
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            if (CommonVariables.PlayerStatus.X == -1) return;
            Win32Support.SetCursorPos(dest_x, dest_y);
            CommonVariables.Pause(10);
            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_RBUTTONDOWN, (IntPtr)0, MakeLParam(dest_x, dest_y));
            CommonVariables.Pause(100);
            Win32Support.SetCursorPos(dest_x + ticks, dest_y);
            CommonVariables.Pause(100);
            Win32Support.SendMessage(hwnd, WindowsMessageCode.WM_RBUTTONUP, (IntPtr)0, MakeLParam(dest_x + ticks, dest_y));

        }
        public void MouseMove2(int ticks)
        {
            IntPtr hwnd = Win32Support.FindWindow("WoW", "World of Warcraft");
            Win32Support.RECT myRect = new Win32Support.RECT();
            Win32Support.GetWindowRect(hwnd, ref myRect);
            
            int dest_x = ((myRect.right - myRect.left) / 2);// *65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            int dest_y = ((myRect.bottom - myRect.top) / 2);// *65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;

            ScrapeScreen();
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            if (CommonVariables.PlayerStatus.Dead) { return; }
            if (CommonVariables.PlayerStatus.Quit) { return; }
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            if (CommonVariables.PlayerStatus.X == -1) return;

            Win32Support.SetCursorPos(dest_x + ticks, dest_y);
        }
        public void FaceDirection(float Degrees)
        {

            FaceDirectionMouse(Degrees, 1, -1);
        }


        public void FaceDirectionMouse(float Degrees)
        {
            FaceDirectionMouse(Degrees,  1, -1);
        }
        public void FaceDirectionMouse(float Degrees, Double allowedVariance, int maxInt)
        {
            if (maxInt == -1) { maxInt = int.MaxValue; }
            if (Degrees > 359) { Degrees = 0.0f; }
            ScrapeScreen();
            if (CommonVariables.PlayerStatus.X == -1) return;
            if (CommonVariables.PlayerStatus.Quit) { return; }
            if (CommonVariables.PlayerStatus.Dead) return;
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            if (CommonVariables.PlayerStatus.inQueue) return;
            if (CommonVariables.PlayerStatus.X == -1) return;

            
            double dir = CommonVariables.PlayerStatus.Facing / 100.0;
            int i = 0;
            while ((Math.Abs((dir - Degrees)) >= allowedVariance) && i < maxInt)
            {
                Application.DoEvents();
                ScrapeScreen();
                if (CommonVariables.PlayerStatus.X == -1) return;
                if (CommonVariables.PlayerStatus.Quit) { return; }
                if (CommonVariables.PlayerStatus.Dead) return;
                if (!CommonVariables.PlayerStatus.ValidScan) { return; }
                if (CommonVariables.PlayerStatus.inQueue) return;

                i++;
                Double calced = (dir - Degrees);
                if (calced > 180) calced = calced + -(calced + 180);
                if (calced <= -0.0001)
                {
                    int time = (int)calced;
                    if (time > -1) time = -1;
                    if ((int)calced >= -3) time = -6;
                    MouseMove(time);
                }
                else
                {
                    int time = (int)Math.Round(calced);
                    if (time < 1) time = 1;

                    if ((int)calced <= 3) time = 4;
                    MouseMove(time);

                }
                //    CommonVariables.Pause(50);
                ScrapeScreen();
                dir = CommonVariables.PlayerStatus.Facing / 100.0;
                if (CommonVariables.PlayerStatus.Dead) return;
                if (CommonVariables.PlayerStatus.Quit) { return; }
                if (!CommonVariables.PlayerStatus.ValidScan) { return; }
                if (CommonVariables.PlayerStatus.X == -1) return;
            }
        }

        public void FaceDirectionMouse2(float Degrees, Double allowedVariance, int maxInt)
        {
            if (maxInt == -1) { maxInt = int.MaxValue; }
            if (Degrees > 359) { Degrees = 0.0f; }
            ScrapeScreen();
            if (CommonVariables.PlayerStatus.X == -1) return;
            if (CommonVariables.PlayerStatus.Quit) { return; }
            if (CommonVariables.PlayerStatus.Dead) return;
            if (!CommonVariables.PlayerStatus.ValidScan) { return; }
            double dir = CommonVariables.PlayerStatus.Facing / 100.0;
            int i = 0;
            while ((Math.Abs((dir - Degrees)) >= allowedVariance) && i < maxInt)
            {
                Application.DoEvents();
                ScrapeScreen();
                if (CommonVariables.PlayerStatus.X == -1) return;
                if (CommonVariables.PlayerStatus.Quit) { return; }
                if (CommonVariables.PlayerStatus.Dead) return;
                if (!CommonVariables.PlayerStatus.ValidScan) { return; }

                i++;
                Double calced = (dir - Degrees);
                if (calced > 180) calced = calced + -(calced + 180);
                if (calced <= -0.0001)
                {
                    int time = (int)calced;
                    if (time > -1) time = -1;
                    if ((int)calced >= -3) time = -6;                

                    MouseMove2(time);
          
                }
                else
                {
                    int time = (int)Math.Round(calced);
                    if (time < 1) time = 1;

                    if ((int)calced <= 3) time = 4;                   

                    MouseMove2(time);
    
                }

                ScrapeScreen();
                dir = CommonVariables.PlayerStatus.Facing / 100.0;
                if (CommonVariables.PlayerStatus.Dead) return;
                if (!CommonVariables.PlayerStatus.ValidScan) { return; }
                if (CommonVariables.PlayerStatus.Quit) { return; }
                if (CommonVariables.PlayerStatus.X == -1) return;
    
            }
        }

        public static double ConvertRadiansToDegrees(double radians)
        {
            double degrees = (180 / Math.PI) * radians;
            return (degrees);
        }
        public static double ConvertDegreesToRadians(double degrees)
        {
            double radians = (Math.PI / 180) * degrees;
            return (radians);
        }

        readonly Double math_rad_90 = ConvertDegreesToRadians(90);

        public Double DirectionToFace(int x, int y)
        {

            ScrapeScreen();

            if (CommonVariables.PlayerStatus.X == -1) return (0.0);
            if (!CommonVariables.PlayerStatus.ValidScan) { return (0.0); }


            Double d_x = CommonVariables.PlayerStatus.X - x;
            Double d_y = (y - CommonVariables.PlayerStatus.Y) * 2.0 / 3.0;

            d_x = d_x / 10000.0;
            d_y = d_y / 10000.0;

            Double direction = Math.Atan2(d_y, d_x);

            double Angle = ConvertRadiansToDegrees(direction + math_rad_90);


            if (Angle < -0.00000000001)
            {
                Angle = Angle + 360;
            }
            return Angle;
        }
        public Double DistanceToPoint(int x, int y)
        {
            ScrapeScreen();

            if (CommonVariables.PlayerStatus.X == -1) return (0.0);

            Double d_x = CommonVariables.PlayerStatus.X - x;
            Double d_y = (y - CommonVariables.PlayerStatus.Y) * 2.0 / 3.0;

            d_x = d_x / 10000.0;
            d_y = d_y / 10000.0;
            Double dist = Math.Pow(d_x * d_x + d_y * d_y, 0.5) * 100;
            return dist;
        }

        public void PlayRunToCoords(int x, int y)
        {
             PlayRunToCoords(x, y,  5, 1.0);
        }
        public void PlayRunToCoords(int x, int y, Double allowedXYVariance)
        {
             PlayRunToCoords(x, y,  allowedXYVariance, 0.5);
        }


        public void PlayRunToCoords(int x, int y, Double allowedXYVariance, Double allowedFaceVariance)
        {
            if (CommonVariables.PlayerStatus.X == -1) return;
            if (CommonVariables.PlayerStatus.Quit) return;
            if (!CommonVariables.PlayerStatus.ValidScan) return;
            ///todo:  set this up so the char will move about the world 
            ///also have to check between move is the char doesn't move turn him left or right 30 degrees  move forward 250 miliseconds
            double[] distarray = new Double[15];
            int count = 0;
            double dist_store = 101;
            while ((Math.Abs(CommonVariables.PlayerStatus.X - x) >= allowedXYVariance || Math.Abs(CommonVariables.PlayerStatus.X - x) <= allowedXYVariance) &&

                   (Math.Abs(CommonVariables.PlayerStatus.Y - y) >= allowedXYVariance || Math.Abs(CommonVariables.PlayerStatus.Y - y) >= allowedXYVariance)
                     && (dist_store > allowedXYVariance)
                   )
            {
                Application.DoEvents();
                Double Angle = DirectionToFace(x, y);
                Double dist1 = DistanceToPoint(x, y) * 1000;
                Double dist = DistanceToPoint(x, y) * 1000;
                if (CommonVariables.PlayerStatus.WSG)
                {
                    dist1 = dist1 / 5;
                    dist = dist / 5;
                }
                FaceDirectionMouse((float)Angle,  allowedFaceVariance, -1);

                dist_store = dist;
                if (dist_store <= allowedXYVariance) return;
                if (dist1 < 3000) { dist = 4000; }
                if (dist1 < 2000) { dist = 3000; }
                if (dist1 < 1000) { dist = 2000; }
                if (dist1 < 500) { dist = 1500; }
                if (dist1 < 400) { dist = 1000; }

                if (dist1 < 250) { dist = 50; }
                if (dist1 < 50) { dist = 50; }
                if (dist1 < 25) { dist = 5; }
                if (CommonVariables.PlayerStatus.InRaid == false)  // if were not in a raid, we want to do little steps to the battle master
                {
                    dist = 5; 
                }
                ScrapeScreen();  //rescrape the screen to get and update on position.  fire events if needed and come back to this.
                Application.DoEvents();
                if (CommonVariables.PlayerStatus.Dead) return;  // were dead!   oh nos.. exit from here and start the next round.
                if (CommonVariables.PlayerStatus.Quit) return; // geuess we want to quit the application.
                if (!CommonVariables.PlayerStatus.ValidScan) return; // note: have to check this.  if this is right then nothing ever gets executed after this line


                SendKeyAndAdjust(Keys.Up, (int)dist,  x, y);



                //this is to try and get unstuck if you run into somthing.
                //this would work better if it guessed paths...
                count = (count + 1) % 15;
                distarray[count] = dist_store;


                if (CommonVariables.PlayerStatus.Quit) return;
            }

            return ;
        }
    }
}
